package com.lwj.springbootvue.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.lwj.springbootvue.constants.HttpStatus;
import com.lwj.springbootvue.exception.ServiceException;
import com.lwj.springbootvue.mapper.UserMapper;
import com.lwj.springbootvue.model.User;
import com.lwj.springbootvue.model.dto.LoginDto;
import com.lwj.springbootvue.model.vo.LoginUser;
import com.lwj.springbootvue.service.UserService;
import com.lwj.springbootvue.util.JwtUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;


@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;


    private final AuthenticationManager authenticationManager;
    private final PasswordEncoder passwordEncoder;

    public UserServiceImpl(AuthenticationManager authenticationManager, PasswordEncoder passwordEncoder) {
        this.authenticationManager = authenticationManager;
        this.passwordEncoder = passwordEncoder;
    }

    /*
    * 登录: 验证登录用户，生成token
    * */
    @Override
    public String login(LoginDto loginDto) {
        //System.out.println(loginDto);

        // 1.封装  authentication 对象 （认证对象，存储登录用户的个人信息）
        UsernamePasswordAuthenticationToken authentication=
                new UsernamePasswordAuthenticationToken(loginDto.getUsername(),loginDto.getPassword());
        // 2.进行校验 调用 authenticationManager对象的 authenticate方法 （用户加密  密码校验）
        Authentication authenticate = null;
        try {
             authenticate = authenticationManager.authenticate(authentication);
        } catch (AuthenticationException ex) {
            // 认证失败，抛出自定义异常或处理异常
            throw new ServiceException(HttpStatus.UNAUTHORIZED, "认证失败密码错误！");
        }

        // 放入的用户信息 (获取Principal)
        LoginUser loginUser=(LoginUser) authenticate.getPrincipal();
        // 生成 token
        String token= JwtUtils.createToken(loginUser);

        System.out.println("token==>:"+token);
        return token;
    }


    // 注册
    @Override
    public boolean register(LoginDto loginDto) {
        // 1.查询用户名是否存在
        User loginUser = userMapper.selectOneByUsername(loginDto.getUsername());
        if(ObjectUtil.isNotNull(loginUser)){
            throw new ServiceException(HttpStatus.ERROR,"用户名或邮箱已被占用");
        }
        // 2. 创建用户类
        User user = new User();
        // 加密密码储存
        BeanUtil.copyProperties(loginDto,user);
        String encodePassword = passwordEncoder.encode(user.getPassword());
        user.setPassword(encodePassword);
        // 3. 插入数据库
        boolean b = userMapper.insertUser(user);
        return b;
    }



    @Override
    public void changeAdminPassword(String newPassword,User user) {
        // 通过token获取登录用户的信息
            // 加密新密码
        if(ObjectUtil.isNull(user)){
            throw new ServiceException(HttpStatus.CONFLICT,"修改密码失败！");
        }
        user.setPassword(passwordEncoder.encode(newPassword));
        System.out.println("用户修改密码成功！"+newPassword);
        // 直接修改密码
        userMapper.changeAdminPassword(user);
    }


}
